package org.dizem.intellipainter;

import org.dizem.intellipainter.component.AboutDialog;
import org.dizem.intellipainter.component.PaintBoard;
import org.dizem.intellipainter.component.SplitLabel;
import org.dizem.intellipainter.component.StatusBar;
import org.dizem.intellipainter.component.color.ColorChooser;
import org.dizem.intellipainter.component.media.AnimationCallback;
import org.dizem.intellipainter.component.media.MediaPanel;
import org.dizem.intellipainter.component.shape.ShapeChooser;
import org.dizem.intellipainter.component.shape.ShapeSelectCallback;
import org.dizem.intellipainter.component.stroke.StrokeChooser;
import org.dizem.intellipainter.component.stroke.StrokeSelectCallback;
import org.dizem.intellipainter.component.tool.ToolChooser;
import org.dizem.intellipainter.component.tool.ToolSelectCallback;
import org.dizem.intellipainter.model.AnimationType;
import org.dizem.intellipainter.model.ShapeType;
import org.dizem.intellipainter.model.StrokeType;
import org.dizem.intellipainter.model.ToolType;
import org.dizem.intellipainter.util.AppletUtil;

import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

/**
 * Entry point of IntelliPainter for Web
 * <p/>
 * User: dizem@126.com
 * Time: 12-2-16 下午10:57
 */
public final class MainFrame extends JApplet {
	public static final Font FONT = new Font("微软雅黑", Font.PLAIN, 13);
	private ToolType toolType = ToolType.Pen;
	private ShapeType shapeType = ShapeType.Point;
	private StrokeType strokeType = StrokeType.Width3;
	private final PaintBoard paintBoard = new PaintBoard(this);
	private final StatusBar statusBar = new StatusBar();
	private final ColorChooser colorChooser = new ColorChooser(this);
	private final java.util.List<Image> imageList = new ArrayList<Image>();

	private final MediaPanel musicPanel = new MediaPanel(new AnimationCallback() {
		public void onChangeAnimationCallback(boolean show) {
			if (show) {
				paintBoard.showAnimation(imageList);
			} else {
				paintBoard.hideAnimation();
			}
		}
	});

	private final ToolChooser toolChooser = new ToolChooser(new ToolSelectCallback() {
		public void onSelectTool(ToolType toolType) {
			MainFrame.this.toolType = toolType;
			statusBar.setStatus(toolType.getText());
		}
	});

	private final ShapeChooser shapeChooser = new ShapeChooser(new ShapeSelectCallback() {
		public void onSelectShape(ShapeType shapeType) {
			MainFrame.this.shapeType = shapeType;
			statusBar.setStatus(shapeType.getText());
		}
	});

	private final StrokeChooser strokeChooser = new StrokeChooser(new StrokeSelectCallback() {
		public void onSelectStroke(StrokeType strokeType) {
			MainFrame.this.strokeType = strokeType;
		}
	});

	@Override
	public void init() {
		super.init();
		musicPanel.init(this);
		colorChooser.init(this);
		for (AnimationType animationType : AnimationType.values()) {
			imageList.add(AppletUtil.getImage(this, animationType.getFilename()));
		}
		UIManager.put("Label.font", FONT);
		UIManager.put("Button.font", FONT);
		UIManager.put("TabbedPane.font", FONT);
		UIManager.put("RadioButton.font", FONT);
		UIManager.put("TitledBorder.font", FONT);
	}

	public MainFrame() {


		setLayout(new BorderLayout());
		setSize(800, 600);
		add(getToolPanel(), BorderLayout.NORTH);
		add(paintBoard, BorderLayout.CENTER);
		add(statusBar, BorderLayout.SOUTH);
		setJMenuBar(getMenuBar());

		paintBoard.addMouseMotionListener(new MouseMotionListener() {
			public void mouseDragged(MouseEvent e) {
			}

			public void mouseMoved(MouseEvent e) {
				statusBar.setCursor(e.getX(), e.getY());
			}
		});

		paintBoard.addMouseListener(new MouseListener() {
			public void mouseClicked(MouseEvent e) {
			}

			public void mousePressed(MouseEvent e) {
			}

			public void mouseReleased(MouseEvent e) {
			}

			public void mouseEntered(MouseEvent e) {
			}

			public void mouseExited(MouseEvent e) {
				statusBar.setCursor(-1, -1);
			}
		});

		toolChooser.setToolType(toolType);
		shapeChooser.setShapeType(shapeType);
		strokeChooser.setStrokeType(strokeType);
	}

	private Component getToolPanel() {
		Box box = Box.createHorizontalBox();
		box.add(toolChooser);
		box.add(new SplitLabel());
		box.add(shapeChooser);
		box.add(new SplitLabel());
		box.add(strokeChooser);
		box.add(new SplitLabel());
		box.add(colorChooser);
		box.add(new SplitLabel());
		box.add(musicPanel);
		box.add(new JPanel());
		box.setPreferredSize(new Dimension(100, 100));
		return box;
	}


	public ToolType getToolType() {
		return toolType;
	}

	public Color getColor1() {
		return colorChooser.getSelectedColor1();
	}

	public Color getColor2() {
		return colorChooser.getSelectedColor2();
	}

	public ShapeType getShapeType() {
		return shapeType;
	}

	public StrokeType getStrokeType() {
		return strokeType;
	}

	private JMenuBar getMenuBar() {
		JMenuBar menuBar = new JMenuBar();

		JMenu menuFile = new JMenu("文件(F)");
		menuFile.setMnemonic('F');
		menuFile.setFont(FONT);
		JMenuItem itemNew = getMenuItem("新建(N)", 'N', new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if (JOptionPane.showConfirmDialog(MainFrame.this, "是否新建画图板", "提示", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
					paintBoard.clear();
				}
			}
		});
		JMenuItem itemSave = getMenuItem("保存(S)", 'S', new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				try {
					JFileChooser fileChooser = new JFileChooser();
					fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
					FileNameExtensionFilter filter = new FileNameExtensionFilter(
							"png", "png");
					fileChooser.setFileFilter(filter);
					if (fileChooser.showSaveDialog(MainFrame.this) == JFileChooser.APPROVE_OPTION) {
						File file = fileChooser.getSelectedFile();
						System.out.println(file.getAbsolutePath());
						if (!file.getAbsolutePath().toLowerCase().endsWith(".png")) {
							file = new File(file.getAbsolutePath() + ".png");
						}
						saveImageToFile(file, paintBoard);
					}
				} catch (Exception ex) {
					JOptionPane.showMessageDialog(MainFrame.this, ex.getMessage());
				}
			}
		});
		menuFile.add(itemNew);
		menuFile.add(itemSave);

		JMenu menuEdit = new JMenu("编辑(E)");
		menuEdit.setMnemonic('E');
		menuEdit.setFont(FONT);
		JMenuItem itemClear = getMenuItem("清空(C)", 'C', new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				paintBoard.clear();
			}
		});
		JMenuItem itemUndo = getMenuItem("撤销(Z)", 'Z', new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				paintBoard.undo();
			}
		});
		menuEdit.add(itemClear);
		menuEdit.add(itemUndo);

		JMenu menuHelp = new JMenu("帮助(H)");
		menuHelp.setMnemonic('H');
		menuHelp.setFont(FONT);
		JMenuItem itemAbout = getMenuItem("关于(A)", 'A', new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				new AboutDialog(MainFrame.this);
			}
		});
		JMenuItem itemHelp = getMenuItem("帮助(H)", 'H', new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				JOptionPane.showMessageDialog(MainFrame.this, "简单小程序不需要帮助");
			}
		});
		menuHelp.add(itemAbout);
		menuHelp.add(itemHelp);


		menuBar.add(menuFile);
		menuBar.add(menuEdit);
		menuBar.add(menuHelp);
		return menuBar;
	}

	private JMenuItem getMenuItem(String text, char mnemonic, ActionListener listener) {
		JMenuItem item = new JMenuItem(text);
		item.setMnemonic(mnemonic);
		item.setFont(FONT);
		item.addActionListener(listener);
		return item;
	}

	public void saveImageToFile(File f, JPanel panel) {
		if (!f.exists()) {
			try {
				f.createNewFile();
			} catch (IOException e) {
				e.printStackTrace();
				return;
			}
		}
		Dimension imageSize = panel.getSize();
		BufferedImage image = new BufferedImage(imageSize.width,
				imageSize.height, BufferedImage.TYPE_INT_ARGB);
		Graphics2D g = image.createGraphics();
		panel.paint(g);
		g.dispose();
		try {
			ImageIO.write(image, "png", f);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}
